#include "main.h"
extern int state[100];
//****************************************************************************************************************************
//*****************************************************页面美化*****************************************************************
////初始化页面
void head_print1(int n)
{
	system("clear");printf("\033[0m");
	printf("************************\033[1;32mWeChat 0.0\033[0m************************\n");
	printf("**\t\t\t\t\t\t\t**\n");
	printf("**\t\t\t");
	if(n==1)printf("\033[1;32m");
	printf("<1>:  登陆\033[0m\t\t\t**\n");
	printf("**\t\t\t");
	if(n==2)printf("\033[1;32m");
	printf("<2>:  注册\033[0m\t\t\t**\n");
	printf("**\t\t\t<3>:  退出\t\t\t**\n");
	printf("**\t\t\t\t\t\t\t**\n");
	printf("**\t\t\t\t\t\t\t**\n");
	printf("**    请按键选择，回车确认\t\t\t\t**\n");
	printf("**********************************************************\n");
}
////主页面
extern pthread_mutex_t pm1;
void head_print2(struct user user,struct contact_link*P,int*option,struct contact_data*case_data)
{

	while(1)
	{
		system("clear");printf("\033[0m");
		printf("************************\033[1;32mWeChat 0.0\033[0m************************\n");
		printf("**   账号: %-20s\t\t\t\t**\n",user.name);
		printf("**\t\t\t\t\t\t\t**\n");
		printf("**\t\t<0>：刷新\t\t\t\t**\n");
		printf("**\t\t<1>：shell+文件助手\t\t\t**\n");
		printf("**\t\t<2>：添加好友\t\t\t\t**\n");
		///////////////////////////////////////////////////////////////////////////////
		pthread_mutex_lock(&pm1);
		struct contact_link*temp=P->next;
		int n=0;
		while(temp!=NULL)
		{
			if(temp->contact_data.type==2)
				n++;
			temp=temp->next;
		}
		printf("**\t\t<3>：好友申请\t\t+%d\t\t**\n",n);
		////好友消息
		printf("**\t\t\t\t\t\t\t**\n");
		printf("** 联系人列表:\t\t\t\t\t\t**\n");
		temp=P->next;n=4;
		while(temp!=NULL)
		{
			if(temp->contact_data.type==1)
			{
				printf("**\t\t<%d>: %-15s\t+%d\t\t**\n",n,temp->contact_data.name,temp->contact_data.message);
				n++;
			}
			temp=temp->next;
		}
		////群聊
		printf("**\t\t\t\t\t\t\t**\n");
		printf("**   群聊列表:\t\t\t\t\t\t**\n");
		temp=P->next;
		while(temp!=NULL)
		{
			if(temp->contact_data.type==3)
			{
				printf("**\t\t<%d>: %-14s\t+%d\t\t**\n",n,temp->contact_data.name,temp->contact_data.message);
				n++;
			}
			temp=temp->next;
		}
		pthread_mutex_unlock(&pm1);
		//////////////////////////////////////////////////////////////////////////////
		printf("**\t\t\t\t\t\t\t**\n");
		printf("**    请按键选择，回车确认\t\t\t\t**\n");
		printf("**********************************************************\n");
		if(0!=*option)
		{
			printf("暂无<%d>选项！！！\n",*option);
		}
		printf("请输入选项:");
		scanf("%d",option);
		while(getchar()!=10);
		if(0<=*option && 6>*option)
			return;
		else if(6<=*option && n>*option)
		{
			pthread_mutex_lock(&pm1);
			temp=P->next;n=6;
			while(NULL!=temp)
			{
				if(1==temp->contact_data.type)
				{
					if(n==*option)
					{
						strcpy(case_data->name,temp->contact_data.name);
						case_data->type=temp->contact_data.type;
						case_data->message=temp->contact_data.message;
						pthread_mutex_unlock(&pm1);
						return;
					}
					n++;
				}
			}
			temp=P->next;
			while(NULL!=temp)
			{
				if(3==temp->contact_data.type)
				{
					if(n==*option)
					{
						strcpy(case_data->name,temp->contact_data.name);
						case_data->type=temp->contact_data.type;
						case_data->message=temp->contact_data.message;
						pthread_mutex_unlock(&pm1);
						return;
					}
					n++;
				}
			}
		}
	}

}

//****************************************************************************************************************************
//*****************************************************登陆功能*****************************************************************
extern void head_print1(int);
void login(struct user* userID,int*C,struct sockaddr_in addr)
{
	struct client_login_data test_login_data={0};
	int n=0,server_ret=1;
	while(1)
	{
		//1、创建套接字
		if((*C=socket(AF_INET,SOCK_STREAM,0))==-1){perror("创建客户端套接字失败");break;}
		head_print1(0);
		//***********************************下一循环提示信息********************************
		if(server_ret==1)//内部错误
		{
			if(n==1){printf("暂无<%d>选项！！！\n",test_login_data.type);n=0;}
		}
		else//服务器返回错误值
		{
			if(test_login_data.type==1)
				if(server_ret==-4)printf("登陆失败,服务器开小差\n");
			else if(test_login_data.type==2)
				if(server_ret==-2||server_ret==-1)printf("注册失败,服务器开小差\n");
			if(server_ret==-5)printf("连接失败,服务器开小差\n");
			server_ret=1;
			test_login_data.type=0;
		}
		//*********************************************************************************
		//
		//***********************************初始状态***************************************
		printf("请输入选项:");
		scanf("%d",&test_login_data.type);
		while(getchar()!=10);
		if(test_login_data.type==1||test_login_data.type==2)
		{
			head_print1(test_login_data.type);
			printf("请输入账号:");
			scanf("%20s",test_login_data.userID.name);while(getchar()!=10);
			printf("请输入密码:");
			scanf("%20s",test_login_data.userID.password);while(getchar()!=10);
			int connect_ret=(connect(*C,(struct sockaddr*)&addr,sizeof(addr)));
			if(connect_ret==-1){server_ret=-5;goto top;}
			write(*C,&test_login_data,sizeof(test_login_data));
			printf("发送完成阻塞等待反馈\n");
			int read_ret=read(*C,&server_ret,4);
			if(read_ret==0){server_ret=-5;goto top;}
			printf("服务器返回值:%d\n",server_ret);
			if(test_login_data.type==1)
			{
				if(server_ret==0)
				{
					memcpy(userID,&test_login_data.userID,sizeof(struct user));
					break;
				}
				if(server_ret==-1)printf("该账号不存在\n");
				if(server_ret==-2)printf("密码错误\n");
				if(server_ret==-3)printf("该账号已登陆\n");
			}
			else if(test_login_data.type==2)
			{
				if(server_ret==0)printf("注册成功\n");
				if(server_ret==-1)printf("账号已存在\n");
			}
			printf("任意键回车确认...");fflush(stdout);
			getchar();
			while(getchar()!=10);
		}
		else if(test_login_data.type==3)
		{
			printf("结束主线程\n");
			//结束读线程
			//****
			//结束主线程
			exit(0);
		}
		else
			n=1;
		top:
		close(*C);
	}
	printf("登陆成功\n");
}

//****************************************************************************************************************************
//*****************************************************数据同步*****************************************************************
extern pthread_mutex_t pm1;//引用锁资源
void update_contact(int C,struct tcp_data*from_data,struct contact_link*P)
{
	if(from_data->type==1000)//初始化同步
	{
		//占用链表锁资源
		pthread_mutex_lock(&pm1);
		struct contact_link*temp;
		//清空链表
		while(P->next!=NULL)
		{
			temp=P->next;
			P->next=temp->next;
			free(temp);
		}
		P->next=NULL;P->tail=P;
	}

	//
	if(from_data->type==1000 || from_data->type==1001)
	{
		read(C,from_data->buf,from_data->size);
		//printf("同步标志:%d 同步大小:%d\n",from_data->type,from_data->size);
		int tempbuf_size=0;short tempname_size=0;
		while(tempbuf_size<from_data->size)
		{
			struct contact_link*P1=malloc(sizeof(struct contact_link));
			//memcpy(&P1->contact_data.name,"0",20);
			
			memcpy(&P1->contact_data.type,from_data->buf+tempbuf_size,4);
			tempbuf_size+=4;
			memcpy(&tempname_size,from_data->buf+tempbuf_size,2);
			tempbuf_size+=2;
			memcpy(P1->contact_data.name,from_data->buf+tempbuf_size,tempname_size);
			tempbuf_size+=tempname_size;
			
			P->tail->next=P1;
			P->tail=P1;
			P1->next=NULL;
			P->len++;
			//printf("同步联系人:<%s>类型:%d\n",P1->contact_data.name,P1->contact_data.type);
		}
	}
	if(from_data->type==1002)
	{
		state[1]=1;
		//释放链表锁资源
		pthread_mutex_unlock(&pm1);
		printf("数据同步完成\n");
	}
}

//****************************************************************************************************************************
//*****************************************************主页功能*****************************************************************
void body(struct user user,int C,struct contact_link*P)
{
	while(1)
	{
		//同步数据
		state[1]=0;//标志位清零
		struct tcp_data data_buf={0};
		data_buf.type=1000;
		if(write(C,&data_buf,4)==-1){perror("发送数据请求失败");return;}
		printf("同步数据请求\n");
		printf("**  数据同步中，请稍后...");fflush(stdout);
		while(state[1]==0);//等待同步完成
		int n=0;struct contact_data case_data;
		head_print2(user,P,&n,&case_data);
		system("clear");printf("\033[0m");
		printf("************************\033[1;32mWeChat 0.0\033[0m************************\n");
		printf("**   账号: %-20s\t\t\t\t**\n",user.name);
		printf("**\t\t\t\t\t\t\t**\n");
		switch(n)
		{
			case 0:
				break;
			case 1://shell+文件助手
			{
				data_buf.type=2000;
				strcpy(data_buf.name,user.name);
				shell_fun(C,&data_buf);
				break;
			}
			case 2://添加好友
			{
				add_friend_fun(C,user.name,&data_buf);
				break;
			}
			case 3://处理好友申请
			{
				request_fun(C,user.name,&data_buf);
				break;
			}
			default:
			{
				if(1==case_data.type)
				{
					data_solo_fun(C,user.name,&data_buf);
				}
				else if(3==case_data.type)
				{
					data_group_fun(C,user.name,&data_buf);
				}
			}

		}
	
	}



}

//****************************************************************************************************************************
//*****************************************************shell指令+文件传输*******************************************************
void shell_fun(int C,struct tcp_data*data_buf)
{
	printf("**\t\t\033[1;32m<1>：shell指令\033[0m\t\t\t\t**\n");
	printf("**\t\t\t\t\t\t\t**\n");
	printf("**    请输入命令，q键退出\t\t\t\t**\n");
	printf("**********************************************************\n");
	while(1)
	{
		state[2]=2999;
		printf("请输入命令:");
		fgets(data_buf->buf,128,stdin);
		data_buf->buf[strlen(data_buf->buf)-1]='\0';
		//printf("命令为:<%ld>%s\n",strlen(to_server->buf),to_server->buf);
		if(strcmp(data_buf->buf,"q")==0)return;
		data_buf->size=strlen(data_buf->buf)+1;
		printf("命令大小为:%d\n",data_buf->size);
		if(strncmp(data_buf->buf,"upload ",7)==0)
		{
			upload_cen(C,data_buf);
		}
		else if(strncmp(data_buf->buf,"download ",9)==0)
		{
			state[2]=2000;
			data_buf->type=2200;
			write(C,data_buf,data_buf->size+28);
			while(2999!=state[2]);
		}
		else
		{
			state[2]=2000;
			data_buf->type=2000;
			write(C,data_buf,data_buf->size+28);
			while(2999!=state[2]);
		}
		
	}
	return;
}

//****************************************************************************************************************************
//*****************************************************上传文件*****************************************************************
void upload_cen(int C,struct tcp_data*data_buf)
{
	char*upload_arg[64]={0};
	char tempbuf[4096]={0};
	memcpy(tempbuf,data_buf->buf,4096);
    upload_arg[0]=strtok(tempbuf," ");
    int i=1;    
    while((upload_arg[i]=strtok(NULL," "))!=NULL)
        i++;
	struct  stat file_date;
	for(int n=1;n<i;n++)
	{
		//printf("当前段:%d,总:%d\n",n,i);
		//文件信息
		long temp_size=0;
		long file_size=0;
		struct  stat file_date;
		printf("upload <%s>",upload_arg[n]);
		if(access(upload_arg[n],F_OK)==-1){printf("upload %s:该文件不存在\n",upload_arg[n]);continue;}
		if(stat(upload_arg[n],&file_date)==-1){perror("获取文件属性失败");continue;}
		file_size=file_date.st_size;
		int FP=open(upload_arg[n],O_RDONLY|O_EXCL);
		if(FP==-1){perror("打开文件失败");continue;}
		//printf("已传输:%ld   总量:%ld\n",temp_size,file_size);
		//存储文件名+总大小
		data_buf->type=2100;
		state[2]=2100;
		short len=strlen(upload_arg[n])+2;
		memcpy(data_buf->buf,&len,2);
		memcpy(data_buf->buf+2,upload_arg[n],len);
		int dd=0;double dd_d=0;
		char dd_f[51]={0};
		printf("大小<%ld>\n",file_size+2+len);
		printf("\r拷贝进度:[%-50s]%d%%",dd_f,dd);fflush(stdout);
		while(temp_size<file_size)
		{
			int ret=read(FP,data_buf->buf+2+len,4096-2-len);
			if(ret==0)continue;
			data_buf->size=ret+2+len;
			write(C,data_buf,data_buf->size+28);
			temp_size+=ret;
			//界面优化
			dd_d=(double)(file_size-temp_size)/file_size;dd=100-(int)(dd_d*100);
			//printf("已拷贝:%ld--总量:%ld\n拷贝进度:%d\n",temp_size,file_date.st_size,dd);
			for(int i=0;i<dd/2;i++)
			{
				dd_f[i]='#';
			}
			dd_f[50]='\0';
			printf("\r拷贝进度:[%-50s]%d%%",dd_f,dd);fflush(stdout);
			usleep(10000);
			data_buf->type=2101;
		}
		close(FP);
		printf("拷贝完成\n");
	}
	// data_buf->type=2999;
	// write(C,data_buf,4);
	return;
}

//****************************************************************************************************************************
//*****************************************************下载文件*****************************************************************

//****************************************************************************************************************************
//*****************************************************添加好友*****************************************************************
void add_friend_fun(int C,char user_name[20],struct tcp_data*to_server)
{	
	system("clear");printf("\033[0m");
	printf("************************\033[1;32mWeChat 0.0\033[0m************************\n");
	printf("**   账号: %-20s\t\t\t\t**\n",user_name);
	printf("**\t\t\t\t\t\t\t**\n");
	printf("**\t\t\033[1;32m<4>：添加好友\033[0m\t\t\t\t**\n");
	return;
}

//****************************************************************************************************************************
//*****************************************************好友申请*****************************************************************
void request_fun(int C,char user_name[20],struct tcp_data*to_server)
{
	system("clear");printf("\033[0m");
	printf("************************\033[1;32mWeChat 0.0\033[0m************************\n");
	printf("**   账号: %-20s\t\t\t\t**\n",user_name);
	printf("**\t\t\t\t\t\t\t**\n");
	printf("**\t\t\033[1;32m<5>：好友申请\033[0m\t\t\t\t**\n");
	return;
}

//****************************************************************************************************************************
//*****************************************************单人聊天*****************************************************************
void data_solo_fun(int C,char user_name[20],struct tcp_data*to_server)
{	
	system("clear");printf("\033[0m");
	printf("************************\033[1;32mWeChat 0.0\033[0m************************\n");
	printf("**   账号: %-20s\t\t\t\t**\n",user_name);
	printf("**\t\t\t\t\t\t\t**\n");
	printf("**\t\t\033[1;32m<1>：单人聊天\033[0m\t\t\t\t**\n");
	return;
}

//****************************************************************************************************************************
//*****************************************************多人聊天*****************************************************************
void data_group_fun(int C,char user_name[20],struct tcp_data*to_server)
{	
	system("clear");printf("\033[0m");
	printf("************************\033[1;32mWeChat 0.0\033[0m************************\n");
	printf("**   账号: %-20s\t\t\t\t**\n",user_name);
	printf("**\t\t\t\t\t\t\t**\n");
	printf("**\t\t\033[1;32m<1>：多人聊天\033[0m\t\t\t\t**\n");
	return;
}

//****************************************************************************************************************************
//*****************************************************主页功能*****************************************************************
void read_fun(int C,struct tcp_data*from_buf)
{	

	return;
}
